home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 25 / CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso / CUCD / Magazine / C_Tutorial / Part-13 / PatchLib / source / RemovePatchProjectA.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-01  |  4.3 KB  |  142 lines

  1. /*
  2. **    patch.library
  3. **
  4. **    Copyright © 1993-1997 by Stefan Fuchs
  5. **        Freely distributable.
  6. */
  7.  
  8. #ifndef _PATCH_INCLUDES_H
  9. #include "patch_includes.h"
  10. #endif
  11.  
  12.  
  13. /****** patch.library/RemovePatchProjectA ***************************************
  14. *
  15. *   NAME
  16. *        RemovePatchProjectA -- Remove all patches from the same project. (V4)
  17. *        RemovePatchProject -- varargs stub for RemovePatchProjectA(). (V4)
  18. *
  19. *   SYNOPSIS
  20. *        Error = RemovePatchProjectA( project, taglist )
  21. *        D0                           A0       A1
  22. *
  23. *        ULONG Error RemovePatchProjectA( APTR, struct TagItem *);
  24. *
  25. *        Error = RemovePatchProject( project, ...)
  26. *
  27. *        ULONG Error RemovePatchProject( APTR, ...);
  28. *
  29. *   FUNCTION
  30. *        Remove all patches from the given project.
  31. *
  32. *        This function simplifies the way, patches can be removed:
  33. *        - All patches belonging to one project will be disabled
  34. *        - The function then waits (depending on PATT_Timeout) until
  35. *          the usagecounters of all patches become zero
  36. *        - Now all patches will be removed via RemovePatchTags()
  37. *        - If all patches are removed resources connected to the
  38. *          project will be deallocted
  39. *
  40. *        You may call this function to cleanup a project, even if no
  41. *        patch was successfully installed for this project.
  42. *
  43. *   INPUTS
  44. *        project = pointer to a patch project obtained via
  45. *                  CreatePatchProject()
  46. *        taglist = pointer to array of tags
  47. *
  48. *   TAGS
  49. *        same as RemovePatchTags()
  50. *
  51. *   RESULT
  52. *        Error = errorcode as defined in patch.h.
  53. *                same as RemovePatchTags()
  54. *
  55. *   NOTES
  56. *        Removing a patch routine can never be made absolutely safe.
  57. *        Although patch.library does anything possible to provide methods
  58. *        to minimize the chance of a crash, there will always be a
  59. *        slight chance.
  60. *        So minimize the number of install and remove operations.
  61. *
  62. *   BUGS
  63. *
  64. *   SEE ALSO
  65. *        CreatePatchProject(), InstallPatchTags(), RemovePatchTags(),
  66. *        patch.h, patchtags.h
  67. *
  68. ******************************************************************************
  69. *
  70. */
  71.  
  72. ULONG LIBFUNC RemovePatchProjectA( REGA0 struct PatchProject *project GNUC_REGA0, REGA1 struct TagItem *taglist GNUC_REGA1)
  73. {
  74. LONG timeout;
  75. ULONG result;
  76. struct Patch *PatchPointer;
  77. struct Node *pointer;
  78. struct TagItem SetPatchDisableTags[2] = { PATT_Disabled, 1L, TAG_DONE };
  79. struct TagItem SetPatchEnableTags[2] = { PATT_Disabled, 0L, TAG_DONE };
  80.  
  81.     if (project == NULL) return(NULL);
  82.  
  83.     timeout = GetTagData(PATT_TimeOut, 0L, taglist);
  84.  
  85.     result = SAVEObtainSemaphore();
  86.     if(result) return(result);
  87.  
  88.  
  89. /* Disable all Project related patches */
  90.  
  91.     project->PPR_Flags |= PPRF_InternalCall;
  92.     Disable();        /* Patches muessen gleichzeitig disabled werden */
  93.     SetPatchProjectA(project, SetPatchDisableTags);
  94.     Enable();
  95.  
  96.  
  97.     result = PATERR_PatchInUse;
  98.     while(result)
  99.  
  100. /* Test usecount of all Project related patches */
  101.     {
  102.         for (pointer = (struct Node *) project->PPR_PatchListHeader.lh_Head;
  103.              pointer->ln_Succ;
  104.              pointer = (struct Node *)pointer->ln_Succ)
  105.         {
  106.             PatchPointer = (struct Patch *) (((UBYTE *)pointer) -offsetof(struct Patch, PS_ProjectNode.mln_Succ));
  107.             result = TestUsage( PatchPointer);
  108.             if( result == PATERR_Ok) break;
  109.         }
  110.  
  111.         if (result)
  112.         {
  113.             timeout -= 30;
  114.             if(timeout  < 1)
  115.             {
  116.                 /* reenabel patches */
  117.                 project->PPR_Flags |= PPRF_InternalCall;
  118.                 Disable();        /* Patches muessen gleichzeitig disabled werden */
  119.                 SetPatchProjectA(project, SetPatchEnableTags);
  120.                 Enable();
  121.                 ReleaseSemaphore(&(PatchBase->PB_Semaphore)); /* Release Semaphore in order not to cause an deadlock */
  122.                 return( result);
  123.  
  124.             }
  125.  
  126.             ReleaseSemaphore(&(PatchBase->PB_Semaphore)); /* Release Semaphore in order not to cause an deadlock */
  127.             MyDelay(30);
  128.             ObtainSemaphore(&(PatchBase->PB_Semaphore));  /* No need to call SAVEObtainSemaphore here, because forbid was already broken by delay */
  129.         }
  130.     }
  131.     for (pointer = (struct Node *) project->PPR_PatchListHeader.lh_Head;
  132.          pointer->ln_Succ;)
  133.     {
  134.         PatchPointer = (struct Patch *) (((UBYTE *)pointer) -offsetof(struct Patch, PS_ProjectNode));
  135.         pointer = (struct Node *)pointer->ln_Succ;
  136.         RemovePatchTagsA(PatchPointer, taglist);
  137.     }
  138.     ADeleteMyListNode((struct Node *)project);
  139.     ReleaseSemaphore(&(PatchBase->PB_Semaphore));
  140.     return( result);
  141. }
  142.